#pragma once

/*
 * my client session to implement anet::tcp::CSharePtrSession.
 */

#include <functional>
#include "share_ptr_session.hpp"
#include "log.h"


// get thread id.
inline unsigned int getThreadId() {
	std::thread::id this_id = std::this_thread::get_id();
	return *(unsigned int*)&this_id;
}

// share pointer session. CClientSession should include SharePtrSession pointer.
class CClientSession;
using sharePtrSession = anet::tcp::CSharePtrSession<CClientSession>;

class CClientSession {
public:
	CClientSession() = default;
	virtual ~CClientSession() = default;

public:
	// create interface.
	static CClientSession* Create() {
		return new CClientSession();
	}

	// on message callback.
	void OnMessage(const char *msg, int len) {
		// const char *content = msg + gProto_head_size;
		// auto msgId = ntohs(*(uint16*)(content));
		// auto size = len - gProto_head_size - gProto_message_id_size;
		// auto &&body = std::string(msg + gProto_head_size + gProto_message_id_size, size);
		// Adebug("msg id:{},msg:{},thread id:{}", msgId, body.c_str(), getThreadId());
		m_netSession->Send(msg, len);
	}

	// on tcp connection connected.
	void OnConnected() {
		Adebug("{}:{} {}, thread id:{}", m_netSession->getRemoteIP(), m_netSession->getRemotePort(), "connected in", getThreadId());
		// add repeated timer.
		m_timer.add_var_repeated_timer(0, 1000, [](std::string a, int b, int c) {
			Adebug("a:{}, b:{}, c:{}", a, b, c);
		}, "1", 2, 3);
	}

	// on tcp connection terminate.
	void OnTerminate() {
		Adebug("{}:{} {}, thread id:{}", m_netSession->getRemoteIP(), m_netSession->getRemotePort(), "disconnected in", getThreadId());
		// m_timer.kill_timer(0); // here is a bug.
	}

	// initialized the m_netSession pointer.
	void SetSession(sharePtrSession* pSession) {
		m_netSession = pSession;
	}

	void OnRelease() {
		Adebug("{} is released", this);
		delete this;
	}

private:
	// share pointer session.
	sharePtrSession *m_netSession{ nullptr };

	// timer
	STimeWheelSpace::CTimerRegister m_timer;
};
